//
//  TicTacOpponent.h
//  TicTacToe
//
//  Created by Tim on 09-11-26.
//  Copyright 2009 Tim Dimsdale. All rights reserved.
//
// This file is part of TicTacToe.
// 
// TicTacToe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// TicTacToe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with TicTacToe.  If not, see <http://www.gnu.org/licenses/>
//
#import <Cocoa/Cocoa.h>
#import "TicTacModel.h"

#define DEFAULT_SKILL_LEVEL 100 // default to all skills

/*!
 \brief The computer's logic
 TicTacOpponent is the computer opponent.
 It is expected the controller will properly notify the opponent when it's his turn.
 */
@interface TicTacOpponent : NSObject {
	/*!
	 The code for the opponent player.  Could be TICTAC_X or TICTAC_O
	 */
	int player;
	
	/*!
	 Any value between 0 and 100 where 0 implies an easier opponent, and 100 implies a harder component.
	 */
	int skillLevel;
	
	/*!
	 A reference to the data model used while analyzing.  This model is not owned by the opponent,
	 it expects somebody else to own it.
	 */
	TicTacModel* model;
}

/*!
 \brief Sets the player code (TICTAC_X or TICTAC_O) for the opponent.
 \param playerCode TICTAC_X or TICTAC_O
 */
-(void) setPlayerCode: (int) playerCode;
/*!
 \brief Sets the skill level of the opponent.
 \param skill 0 means weaker skill, 100 means more difficult.
 */
-(void) setSkillLevel: (int) skill;

/*!
 \brief The main method expected to be invoked from the controller. This will let the computer take a turn.
 \param error Allow an error code if the computer cannot take a turn properly.
 */
-(void) takeTurn:  (NSError**)error;
/*!
 \brief Used internally, do not call directly.  Call takeTurn instead.
 \param x the output x position if it made a decision
 \param y the output y position if it made a decision 
 \return Whether or not it was successfull is making a decision.
 Logic checks to see if it can make a winning decision.
 */
-(BOOL) makeWinningDecisionXOut: (int*)x yOut:(int*)y;		

/*!
 \brief Used internally, do not call directly.  Call takeTurn instead.
 \param x the output x position if it made a decision
 \param y the output y position if it made a decision 
 \return Whether or not it was successfull is making a decision.
 Logic checks to see if it can block the other player.
 */
-(BOOL) makeBlockingDecisionXOut: (int*)x yOut:(int*)y;		

/*!
 \brief Used internally, do not call directly.  Call takeTurn instead.
 \param x the output x position if it made a decision
 \param y the output y position if it made a decision 
 \return Whether or not it was successfull is making a decision.
 Checks to see if it can make strategic decision.
 */
-(BOOL) makeStrategicDecisionXOut: (int*)x yOut:(int*)y;	

/*!
 \brief Used internally, do not call directly.  Call takeTurn instead.
 \param x the output x position if it made a decision
 \param y the output y position if it made a decision 
 \return Whether or not it was successfull is making a decision.
 As the name implies, makes a completely random decision.
 */
-(BOOL) makeRandomDecisionXOut: (int*)x yOut:(int*)y;		
/*!
 \brief Used internally, do not call directly.  Call takeTurn instead.
 \param x the output x position if it made a decision
 \param y the output y position if it made a decision 
 \return Whether or not it was successfull is making a decision.
 Last resort.  Ideally should never be called, however random is... random and there is no guarantee
 that a decision can be made randomly before it reaches the sanity check.
 */
-(BOOL) makeDesperateDecisionXout: (int*)x yOut:(int*)y ;	

/*!
 \brief Sets the data model to use for analysis.  It is expected somebody else will own the model.
 \param currentModel The data model to use
 */
-(void) setModel: (TicTacModel*) currentModel ;

/*!
 \brief Helper method expected to be used internally.   In 0,1,2 it will return the other two numbers that are different than the value put in.
 \param inCheck The input number
 \param a first output
 \param b second output
 */
-(void) getPositionsOtherThan: (int)inCheck outOtherA:(int*)a outOtherB:(int*)b ;

@end
